package com.wadesss.flyingformationapp

import android.Manifest
import android.annotation.SuppressLint
import android.app.AlertDialog
import android.bluetooth.BluetoothManager
import android.content.*
import android.os.Build
import android.os.Bundle
import android.os.Handler
import android.os.Looper
import android.view.Menu
import android.view.MenuItem
import android.view.View
import android.widget.Button
import android.widget.Toast
import androidx.appcompat.app.AppCompatActivity
import retrofit2.http.*
import androidx.recyclerview.widget.LinearLayoutManager
import androidx.recyclerview.widget.RecyclerView
import com.google.android.material.textfield.TextInputEditText
import com.inuker.bluetooth.library.beacon.Beacon
import com.inuker.bluetooth.library.search.SearchRequest
import com.inuker.bluetooth.library.search.SearchResult
import com.inuker.bluetooth.library.search.response.SearchResponse
import com.inuker.bluetooth.library.utils.BluetoothLog
import com.tbruyelle.rxpermissions3.RxPermissions
import okhttp3.MediaType
import okhttp3.RequestBody
import org.json.JSONException
import org.json.JSONObject
import retrofit2.Call
import retrofit2.Callback
import retrofit2.Response
import retrofit2.Retrofit
import retrofit2.converter.gson.GsonConverterFactory

class LoginPorts {
    val allowGcsCount: String = ""
    val port: String = ""
}

class LoginData {
    val username: String = ""
    val token: String = ""
    val ports: List<LoginPorts>? = null
}

class LoginMessage {
    val code: String = ""
    val data: LoginData? = null
    val msg: String = ""
}

interface APIService {
    @POST("userService/login")
    fun login(@Body requestBody: RequestBody?): Call<LoginMessage?>?
}

class ConnectReceiver: BroadcastReceiver() {
    private var bind:IBind? = null

    override fun onReceive(context: Context?, intent: Intent?) {
        when(intent?.action)
        {
            "start_server" -> {
                this.bind?.start_server(intent)
            }

            "stop_server" -> {
                this.bind?.stop_server(intent)
            }

            "enable.btn" -> {
                this.bind?.enableBtn(intent)
            }

            "disable.btn" -> {
                this.bind?.disableBtn(intent)
            }

            "disconn" -> {
                this.bind?.disconn(intent)
            }
        }
    }

    fun setBind(bd: IBind) {
        this.bind = bd
    }

    interface IBind {
        fun start_server(intent: Intent)
        fun stop_server(intent: Intent)
        fun enableBtn(intent: Intent)
        fun disableBtn(intent: Intent)
        fun disconn(intent: Intent?)
    }
}


class ConnectActivity : AppCompatActivity(), ConnectReceiver.IBind {

    private val rxPermissions = RxPermissions(this)
    private var mDeviceList: MutableList<BluetoothItem> = mutableListOf()
    private lateinit var adapter: BluetoothItemAdapter
    lateinit var recyclerView: RecyclerView

    private var localReceiver = ConnectReceiver()


    override fun onRequestPermissionsResult(
        requestCode: Int,
        permissions: Array<out String>,
        grantResults: IntArray
    ) {
        super.onRequestPermissionsResult(requestCode, permissions, grantResults)

        when (requestCode) {
            1 -> {

                // 如果请求被取消，则结果数组为空。
                if (grantResults.isNotEmpty()) {

                } else {

                }
                return
            }
        }
    }

    override fun onCreateOptionsMenu(menu: Menu?): Boolean {
        menuInflater.inflate(R.menu.bottom_nav_menu, menu)
        return super.onCreateOptionsMenu(menu)
    }

    @SuppressLint("CutPasteId")
    override fun onOptionsItemSelected(item: MenuItem): Boolean {
        when(item.itemId) {
            R.id.btn_login -> {
                val builder = androidx.appcompat.app.AlertDialog.Builder(this)
                builder.setTitle("编队系统登陆信息")
                builder.setCancelable(false)
                val setting = layoutInflater.inflate(R.layout.layout_login, null)
                builder.setView(setting)

                // 取出登陆信息
                val pref = getSharedPreferences("Configure", 0)
                val edit = pref.edit()

                var user = pref.getString("UserName", "")
                var passwd = pref.getString("Passwd", "")
                val userEdit = setting.findViewById<TextInputEditText>(R.id.username)
                val passwdEdit = setting.findViewById<TextInputEditText>(R.id.password)
                userEdit.text?.clear()
                userEdit.text?.append(user)
                passwdEdit.text?.clear()
                passwdEdit.text?.append(passwd)

                val dialog = builder.show()

                val btnSave = setting.findViewById<Button>(R.id.sign_in_button)
                btnSave.setOnClickListener {

                    user = userEdit.text.toString()
                    passwd = passwdEdit.text.toString()
                    edit.putString("UserName", user)
                    edit.putString("Passwd", passwd)
                    edit.apply()
                    Toast.makeText(App.instance.applicationContext, "保存成功", Toast.LENGTH_LONG)
                        .show()

                    dialog.dismiss()
                }

                val btnClose = setting.findViewById<Button>(R.id.sign_close)
                btnClose.setOnClickListener {
                    dialog.dismiss()
                }
            }
        }

        return super.onOptionsItemSelected(item)
    }

    @SuppressLint("InlinedApi", "SetTextI18n", "CutPasteId", "CommitPrefEdits")
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_connect)

        rxPermissions
        .request(
            Manifest.permission.ACCESS_COARSE_LOCATION,
            Manifest.permission.ACCESS_FINE_LOCATION,
            Manifest.permission.BLUETOOTH,
            Manifest.permission.BLUETOOTH_ADMIN,
            Manifest.permission.MOUNT_UNMOUNT_FILESYSTEMS,
            Manifest.permission.WRITE_EXTERNAL_STORAGE,
            Manifest.permission.WAKE_LOCK,
        )
        .subscribe { granted ->
            if (granted) { // Always true pre-M
                // I can control the camera now
            } else {
                // Toast.makeText(applicationContext, "获取权限失败", Toast.LENGTH_LONG).show()
            }
        }

        val filter = IntentFilter()
        filter.addAction("start_server")
        filter.addAction("stop_server")
        filter.addAction("enable.btn")
        filter.addAction("disable.btn")
        filter.addAction("disconn")
        App.instance.localBroadcastManager!!.registerReceiver(localReceiver, filter)
        localReceiver.setBind(this)

        val dm = findViewById<TextInputEditText>(R.id.domain_txt)
        val pm = findViewById<TextInputEditText>(R.id.port_txt)

        val pref = getSharedPreferences("Configure", 0)
        val domain = pref.getString("domain", "122.9.106.181")
        val port = pref.getString("port", "")

        if (domain != null) {
            if (domain.isNotEmpty())
            {
                dm.text!!.clear()
                dm.text!!.append(domain)
            }
        }

        if (port != null) {
            if (port.isNotEmpty())
            {
                pm.text!!.clear()
                pm.text!!.append(port)
            }
        }

        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
            rxPermissions
                .request(
                    Manifest.permission.BLUETOOTH_PRIVILEGED,
                    Manifest.permission.REQUEST_INSTALL_PACKAGES
                )
                .subscribe { granted ->
                    if (granted) { // Always true pre-M
                        // I can control the camera now
                    } else {
                        // Toast.makeText(applicationContext, "蓝牙权限失败", Toast.LENGTH_LONG).show()
                    }
                }
        }

        // 禁用启动服务按钮
        val startServer = findViewById<Button>(R.id.connection_btn)
        startServer.isEnabled = false

        App.instance.bluetoothManager = this.getSystemService(Context.BLUETOOTH_SERVICE) as BluetoothManager

        recyclerView = findViewById<View>(R.id.list_view) as RecyclerView
        recyclerView.layoutManager = LinearLayoutManager(this, LinearLayoutManager.VERTICAL, false)
        adapter = BluetoothItemAdapter(mDeviceList, this)
        recyclerView.adapter = adapter

        val searchBtn = findViewById<Button>(R.id.search_btn)
        searchBtn.setOnClickListener {
            mDeviceList.clear()
            adapter.notifyDataSetChanged()

            val request = SearchRequest.Builder()
                // .searchBluetoothLeDevice(3000, 3) // 先扫BLE设备3次，每次3s
                .searchBluetoothClassicDevice(5000) // 再扫经典蓝牙5s
                // .searchBluetoothLeDevice(2000) // 再扫BLE设备2s
                .build()

            App.instance.mClient.search(request, object : SearchResponse {
                override fun onSearchStarted() {}
                override fun onDeviceFounded(device: SearchResult) {
                    val beacon = Beacon(device.scanRecord)
                    val isFound =
                        mDeviceList.firstOrNull { obj -> obj.device_name == device.name && (!device.name.isNullOrEmpty()) } != null
                    if (!isFound) {
                        mDeviceList.add(BluetoothItem(device.name, device.address))
                        adapter.notifyDataSetChanged()

                        BluetoothLog.v(
                            String.format(
                                "beacon for %s: %s\n%s",
                                device.name,
                                device.address,
                                beacon.toString()
                            )
                        )
                    }
                }

                override fun onSearchStopped() {

                }

                override fun onSearchCanceled() {}
            })
        }

        startServer.setOnClickListener {
            if (App.instance.isRun) {
                App.instance.isRun = false
                startServer.text = "启动服务"
                App.instance.mSocket.close()
                return@setOnClickListener
            }

            val pref = getSharedPreferences("Configure", 0)
            val editor = pref.edit()

            if (pm.text.isNullOrEmpty()
                || dm.text.isNullOrEmpty()) {
                Toast.makeText(App.instance.applicationContext, "域名或端口号不能为空", Toast.LENGTH_LONG).show()
                return@setOnClickListener
            }

            editor.putString("domain", dm.text.toString())
            editor.putString("port", pm.text.toString())
            editor.apply()

            startServer.text = "正在启动..."
            startServer.isEnabled = false
            App.instance.isRun = true

            startService(Intent(App.instance, SocketService::class.java))
        }

        val testBtn = findViewById<Button>(R.id.test_btn)
        testBtn.setOnClickListener {
            val user = pref.getString("UserName", "").toString()
            val passwd = pref.getString("Passwd", "").toString()
            if (user.isNotEmpty()
                && passwd.isNotEmpty())
            {
                val retrofit = Retrofit.Builder()
                    .baseUrl("http://122.9.106.181:915/api/")
                    .addConverterFactory(GsonConverterFactory.create())
                    .build()

                val root = JSONObject()
                try {
                    root.put("UserName", user)
                    root.put("pwd", passwd)
                    root.put("sessionid", "null")
                } catch (e: JSONException) {
                    e.printStackTrace()
                }

                val requestBody =
                    RequestBody.create(MediaType.parse("application/json"), root.toString())

                val api = retrofit.create(APIService::class.java)
                val call = api.login(requestBody)
                call!!.enqueue(object : Callback<LoginMessage?> {
                    override fun onResponse(
                        call: Call<LoginMessage?>?,
                        response: Response<LoginMessage?>?
                    ) {
                        if (response != null) {
                            if (response.code() == 200) {
                                val data = response.body()
                                when {
                                    data!!.code == "0" -> {
                                        Toast.makeText(
                                            App.instance.applicationContext,
                                            "登陆成功",
                                            Toast.LENGTH_LONG
                                        ).show()

                                        val edit = pref.edit()
                                        edit.putString("token", data!!.data!!.token)
                                        edit.apply()
                                    }
                                    else ->
                                    {
                                        Toast.makeText(
                                            App.instance.applicationContext,
                                            "登陆失败",
                                            Toast.LENGTH_LONG
                                        ).show()
                                    }
                                }
                            }
                        }

                    }

                    override fun onFailure(call: Call<LoginMessage?>?, t: Throwable?) {
                        Toast.makeText(
                            App.instance.applicationContext,
                            "登陆失败",
                            Toast.LENGTH_LONG
                        ).show()
                    }
                })
            }
        }
    }

    override fun start_server(intent: Intent) {
        val startServer = findViewById<Button>(R.id.connection_btn)
        startServer.text = "断开服务"
        startServer.isEnabled = true
        startActivity(Intent(App.instance, MainActivity::class.java))
        finish()
    }

    override fun stop_server(intent: Intent) {
        val startServer = findViewById<Button>(R.id.connection_btn)
        startServer.text = "启动服务"
        startServer.isEnabled = true
    }

    override fun enableBtn(intent: Intent) {
        val x = recyclerView.childCount
        var i = 0
        while (i < x) {
            val holder = recyclerView.getChildViewHolder(recyclerView.getChildAt(i))
            val btn = holder.itemView.findViewById<Button>(R.id.join_conn_btn)
            btn.isEnabled = true
            ++i
        }
    }

    override fun disableBtn(intent: Intent) {
        val x = recyclerView.childCount
        var i = 0
        while (i < x) {
            val holder = recyclerView.getChildViewHolder(recyclerView.getChildAt(i))
            val btn = holder.itemView.findViewById<Button>(R.id.join_conn_btn)
            btn.isEnabled = false
            ++i
        }
    }

    override fun disconn(intent: Intent?) {
        val x = recyclerView.childCount
        var i = 0
        while (i < x) {
            val holder = recyclerView.getChildViewHolder(recyclerView.getChildAt(i))
            val btn = holder.itemView.findViewById<Button>(R.id.join_conn_btn)
            btn.isEnabled = true
            btn.text = "连接"
            ++i
        }
    }
}